<?php


namespace tmcore\services;

use app\common\model\setting\Config as ConfigModel;
use app\common\model\setting\ConfigSms as ConfigSmsModel;
use app\common\model\setting\ConfigUpload as ConfigUploadModel;
use app\common\model\setting\ConfigPay as ConfigPayModel;

class ConfigService
{
    //配置采用缓存存储，加快响应速度
    //配置缓存打标签，统一处理标签缓存
    //缓存分散存储，避免大key问题
    //统一获取和设置配置的方法

    /**
     * 获取配置
     * @param string $name 配置名称  all-全部 配置-单个(.可获得配置数组的键值)
     * @param string $scope 范围 all-全部 sys-系统配置 pay-支付配置 sms-短信配置 upload-上传配置 api-接口配置 auth-权限配置 addons-插件 run-运行配置 core-系统核心配置 env-系统环境配置
     * @return array 返回配置信息数组
     */
    public function getConfig($name = '', $scope = '')
    {
        $scope_types = ['all', 'sys', 'pay', 'sms', 'upload', 'api', 'auth', 'addons', 'run', 'core', 'env'];
        if(!in_array($scope, $scope_types)) return [];

        return $this->setConfig('get', $scope, $name);
    }

    /**
     * 根据条件获取参数
     * @param string $name 参数
     * @param array $settings 配置信息
     * @return bool|array|string
     */
    private function getExplodeValue($name = '', $settings = [])
    {
        $arr = explode('.', $name);
        $result = [];

        if ($name == 'all') {
            return $settings;
        } else {
            if (isset($settings[$arr[0]]) && $settings[$arr[0]]) {
                $result = $settings[$arr[0]];
                if (isset($arr[1]) && isset($result[$arr[1]])) {
                    $result = $result[$arr[1]];
                }
            }
        }

        return $result;
    }

    /**
     * 设置配置
     * @param string $type 形式 create-创建 get-获取
     * @param string $scope 范围 all-全部 sys-系统配置 pay-支付配置 sms-短信配置 upload-上传配置 api-接口配置 auth-权限配置 addons-插件 run-运行配置 core-系统核心配置 env-系统环境配置
     * @param string $name 配置名称 all-全部 配置-单个(.可获得配置数组的键值)
     * @return array|mixed
     */
    public function setConfig($type = 'create', $scope = 'all', $name = 'all')
    {
        if(strpos($name, '.') !== false) {
            $set_name = explode('.', $name)[0];
        } else {
            $set_name = $name;
        }

        switch ($scope) {
            case 'sys':
                $settings = $this->setSysConfig($type, $set_name);
                break;

            case 'pay':
                $settings = $this->setPayConfig($type, $set_name);
                break;

            case 'sms':
                $settings = $this->setSmsConfig($type, $set_name);
                break;

            case 'upload':
                $settings = $this->setUploadConfig($type, $set_name);
                break;

            case 'run':
                $settings = $this->getRunConfig($type);
                break;

            case 'auth':
                $settings = $this->setAuthConfig($type);
                break;

            case 'addons':
                $settings = $this->setAddonsConfig($type);
                break;

            case 'core':
                $settings = $this->getCoreConfig();
                break;

            case 'env':
                $settings = $this->getEnvConfig();
                break;

            case 'all':
                $settings['sys'] = $this->setSysConfig($type);
                $settings['pay'] = $this->setPayConfig($type);
                $settings['sms'] = $this->setSmsConfig($type);
                $settings['upload'] = $this->setUploadConfig($type);
                $settings['run'] = $this->getRunConfig($type);
                $settings['auth'] = $this->setAuthConfig($type);
                $settings['addons'] = $this->setAddonsConfig($type);
                $settings['core'] = $this->getCoreConfig();
                $settings['env'] = $this->getEnvConfig();
                break;

            default:
                $settings = [];
                break;
        }

        if($settings) {
            $settings = $this->getExplodeValue($name, $settings);
        } else {
            $settings = [];
        }

        return $settings;

    }

    /**
     * 获取缓存句柄
     * @param string $tag
     * @return object
     */
    private static function getCacheService($tag = '') {
        return CacheService::handler($tag);
    }

    /**
     * 获取配置公共方法
     * @param string $type 设置方式 create-创建 get-检验获取
     * @param string $name 获取标识 all-全部 default-默认
     * @param string $prefix 缓存前缀
     * @param object $model 数据库model
     * @param string $field_key 标识字段
     * @param string $field_value 参数字段
     * @param bool $is_default 是否默认
     * @return array
     */
    private function getConfigParams($type, $name, $prefix, $model, $field_key = 'name', $field_value = 'value', $is_default = false) {
        $settings = [];
        $cacheService = self::getCacheService($prefix);

        if ($type == 'create') {
            // 创建并检验缓存，数据库获取循环创建缓存
            $list = $model->column( $field_key . ',' . $field_value . ($is_default?(',is_default'):''), $field_key);
            if($name == 'all') $cacheService->clear($prefix); //清空标签
            foreach ($list as $key => $value) {
                if($is_default && (!empty($value['is_default']))) $cacheService->set($prefix .'_default', $key);
                if($name == 'all' || $name == $key) {
                    $value = ($value[$field_value] && is_string($value[$field_value]))?json_decode($value[$field_value], true):[];
                    $cacheService->set($prefix .'_' .$key, $value);
                    $settings[$key] = $value;
                }
            }
        } elseif ($type == 'get') {
            if($name == 'all') {
                // 根据缓存标签获取全部缓存并循环获取
                $list = CacheService::getTagItems($prefix);
                if(!$list) return $this->getConfigParams('create', $name, $prefix, $model, $field_key, $field_value, $is_default);
                foreach ($list as $key) {
                    // 根据缓存标签截取标识
                    if(strpos($key,'_') !== false) {
                        $key_arr = explode("_",$key);
                        $key = end($key_arr);
                    }
                    if($key != 'default') {
                        $cache = CacheService::get($prefix . '_' . $key);
                        if(!$cache) {
                            $row = $model->where([$field_key => $key])->field($field_key . ',' . $field_value . ($is_default?',is_default':''))->findOrEmpty()->toArray();
                            if($row) {
                                if($is_default && (!empty($row['is_default']))) $cacheService->set($prefix .'_default', $key);
                                $value = ($row[$field_value] && is_string($row[$field_value]))?json_decode($row[$field_value], true):[];
                                $cacheService->set($prefix .'_' . $key, $value);
                                $settings[$key] = $value;
                            }
                        } else {
                            $settings[$key] = $cache;
                        }
                    }
                }
            } else {
                if($name == 'default' && $is_default) {
                    // 获取默认配置标识
                    $name = CacheService::get($prefix . '_default');
                    if(!$name) {
                        $name = $model->where(['is_default' => 1])->value($field_key);
                        if($name) {
                            $cacheService->set($prefix .'_default', $name);
                        } else {
                            $name = '';
                        }
                    }
                    $settings['default'] = $name;
                } else {
                    // 根据缓存获取配置
                    $cache = CacheService::get($prefix . '_' . $name);
                    if(!$cache) {
                        $row = $model->where([$field_key => $name])->field($field_key.','.$field_value . ($is_default?',is_default':''))->findOrEmpty()->toArray();
                        if($row) {
                            if($is_default && (!empty($row['is_default']))) $cacheService->set($prefix .'_default', $name);
                            $value = ($row[$field_value] && is_string($row[$field_value]))?json_decode($row[$field_value], true):[];
                            $cacheService->set($prefix .'_' . $name, $value);
                            $settings[$name] = $value;
                        }
                    } else {
                        $settings[$name] = $cache;
                    }
                }
            }
        }

        return $settings;
    }

    /**
     * 设置系统配置
     * @param string $type 设置方式 create-创建 get-检验获取
     * @param string $name
     * @return array
     */
    private function setSysConfig($type = 'create', $name = 'all')
    {
        $prefix = 'sys_config';
        $configModel = (new ConfigModel);

        return $this->getConfigParams($type, $name, $prefix, $configModel, 'name', 'value');
    }

    /**
     * 设置支付配置
     * @param string $type 设置方式 create-创建 get-检验获取
     * @param string $name
     * @return array
     */
    private function setPayConfig($type = 'create', $name = 'all')
    {
        $prefix = 'pay_config';
        $configModel = (new ConfigPayModel);

        return $this->getConfigParams($type, $name, $prefix, $configModel, 'identify', 'params');
    }

    /**
     * 设置短信配置
     * @param string $type 设置方式 create-创建 get-检验获取
     * @param string $name all-全部 default-默认
     * @return array
     */
    private function setSmsConfig($type = 'create', $name = 'all')
    {
        $prefix = 'sms_config';
        $configModel = (new ConfigSmsModel);

        return $this->getConfigParams($type, $name, $prefix, $configModel, 'identify', 'params' , true);
    }

    /**
     * 设置上传配置
     * @param string $type 设置方式 create-创建 get-检验获取
     * @param string $name all-全部 default-默认
     * @return array
     */
    private function setUploadConfig($type = 'create', $name = 'all')
    {
        $prefix = 'upload_config';
        $configModel = (new ConfigUploadModel);

        return $this->getConfigParams($type, $name, $prefix, $configModel, 'identify', 'params' , true);
    }

    /**
     * 设置权限配置
     * @param string $type 设置方式 create-创建 check-检验获取
     * @return array
     */
    private function setAuthConfig($type = 'create')
    {
        $key = 'auth_config';
        $settings = [];
        $cacheService = self::getCacheService($key);

        if ($type == 'create') {
            $value = (new ConfigModel)->where(['name' => 'auth'])->value('value');
            $settings = json_decode($value, true);
            $cacheService->set($key, json_encode($settings));
        } elseif ($type == 'check') {
            $cache = CacheService::get($key);
            if (!$cache) {
                $value = (new ConfigModel)->where(['name' => 'auth'])->value('value');
                $settings = json_decode($value, true);

                $cacheService->set($key, json_encode($settings));
            } else {
                $settings = json_decode($cache, true);
            }
        }

        return $settings;
    }

    /**
     * 设置插件权限配置
     * @param string $type 设置方式 create-创建 check-检验获取
     * @return array
     */
    private function setAddonsConfig($type = 'create')
    {
        $key = 'sys_addons';
        $settings = [];
        $cacheService = self::getCacheService($key);

        if ($type == 'create') {
            $value = (new ConfigModel)->where(['name' => 'addons'])->value('value');
            $settings = json_decode($value, true);
            $cacheService->set($key, json_encode($settings));
        } elseif ($type == 'check') {
            $cache = CacheService::get($key);
            if (!$cache) {
                $value = (new ConfigModel)->where(['name' => 'addons'])->value('value');
                $settings = json_decode($value, true);

                $cacheService->set($key, json_encode($settings));
            } else {
                $settings = json_decode($cache, true);
            }
        }

        return $settings;
    }

    /**
     * 获取运行时的配置
     * @param string $name
     * @return array
     */
    private function getRunConfig($name = '')
    {
        // 队列运行配置状况
        return [];
    }

    /**
     * 获取系统核心配置
     * @return array
     */
    private function getCoreConfig()
    {
        return config('core');
    }

    /**
     * 获取系统环境配置
     * @return array
     */
    private function getEnvConfig()
    {
        $settings['os'] = PHP_OS; // 服务器操作系统
        $settings['server_software'] = $_SERVER['SERVER_SOFTWARE']; // 服务器环境
        $settings['dns'] = $_SERVER['HTTP_HOST']; // 服务器域名
        $settings['ip'] = gethostbyname($_SERVER['SERVER_NAME']); // 服务器IP
        $settings['port'] = $_SERVER['SERVER_PORT']; // 端口
        $settings['php_version'] = PHP_VERSION; // php版本
        $settings['php_api'] = php_sapi_name(); // php运行方式
        $settings['disk_free_space'] = round( ( disk_free_space(".") / ( 1024 * 1024 * 1024 ) ) , 2 ) . 'G'; // 服务器可用空间
        $settings['upload_max_filesize'] = @ini_get('file_uploads') ? ini_get('upload_max_filesize') : 'unknow'; // 文件上传限制
        $settings['gd_version'] = gd_info()['GD Version']; // GD（图形处理）版本
        $settings['max_execution_time'] = ini_get("max_execution_time") . "秒"; // 最大执行时间

        return $settings;
    }
}